package com.javacoo.fastdfs.client.internal.pool;

import java.io.IOException;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;

import com.javacoo.fastdfs.client.api.pool.StorageClient1Wrapper;
import com.javacoo.fastdfs.client.api.pool.StorageClient1WrapperPool;
import com.javacoo.fastdfs.client.config.FastDFSConfig;
import com.javacoo.fastdfs.client.exception.JccfcFastDFSException;

import lombok.extern.slf4j.Slf4j;

/**
 * StorageClient1Wrapper对象池默认实现
 * @author: duanyong@jccfc.com
 * @since: 2020/4/30 10:55
 */
@Slf4j
public class DefaultStorageClient1WrapperPool implements StorageClient1WrapperPool {
    /** StorageClient1Wrapper对象池 */
    private GenericObjectPool<StorageClient1Wrapper> pool;
    /**
     * 初始化
     * @author duanyong@jccfc.com
     * @date 2020/4/30 11:20
     * @Params fastDFSConfig 配置
     * @return StorageClientPool
     */
    @Override
    public StorageClient1WrapperPool init(FastDFSConfig fastDFSConfig) throws Exception {
        if (fastDFSConfig.getConnectTimeout() <= 0) {
            fastDFSConfig.setConnectTimeout(ClientGlobal.DEFAULT_CONNECT_TIMEOUT * 1000);
        }
        if (fastDFSConfig.getNetworkTimeout() <= 0) {
            fastDFSConfig.setNetworkTimeout(ClientGlobal.DEFAULT_NETWORK_TIMEOUT * 1000);
        }
        if (fastDFSConfig.getTrackerHttpPort() <= 0) {
            fastDFSConfig.setTrackerHttpPort(FastDFSConfig.DEFAULT_TRACKER_HTTP_PORT);
        }
        if (fastDFSConfig.getCharset() == null || fastDFSConfig.getCharset().length() == 0) {
            fastDFSConfig.setCharset(FastDFSConfig.DEFAULT_CHARSET);
        }
        if (fastDFSConfig.getTrackerServers() == null || fastDFSConfig.getTrackerServers().length() == 0) {
            throw new JccfcFastDFSException("tracker地址未配置[trackerServers]", -1);
        }
        if (fastDFSConfig.isAntiStealToken()) {
            if (fastDFSConfig.getSecretKey() == null || "".equals(fastDFSConfig.getSecretKey().trim())) {
                throw new JccfcFastDFSException("未配置[secretKey]", -2);
            }
        }
        initClientGlobal(fastDFSConfig);
        pool = new GenericObjectPool<>(new StorageClient1WrapperFactory(),initPoolConfig(fastDFSConfig.getPoolConfig()));
        this.dumpPoolInfo();
        return this;
    }
    /**
     * 获取StorageClient1Wrapper
     * @author duanyong@jccfc.com
     * @date 2020/4/30 11:01
     * @return: org.csource.fastdfs.StorageClient
     */
    @Override
    public StorageClient1Wrapper getClient() throws Exception {
        StorageClient1Wrapper storageClient1Wrapper = pool.borrowObject();
        log.debug("DefaultStorageClient1WrapperPool->getClient->{}",storageClient1Wrapper.hashCode());
        return storageClient1Wrapper;
    }
    /**
     * 释放StorageClient1Wrapper
     * @author duanyong@jccfc.com
     * @date 2020/4/30 11:01
     * @param storageClient1Wrapper: StorageClient1Wrapper
     * @return: void
     */
    @Override
    public void releaseClient(StorageClient1Wrapper storageClient1Wrapper) {
        try {
            pool.returnObject(storageClient1Wrapper);
            log.debug("DefaultStorageClient1WrapperPool->releaseClient->{}",storageClient1Wrapper.hashCode());
        } catch (Exception e) {
            log.error("释放StorageClient1Wrapper异常：",e);
        }
    }
    /**
     * 打印连接池情况
     * <p>说明:</p>
     * @author duanyong@jccfc.com
     * @date 2020/4/30 14:01
     */
    @Override
    public void dumpPoolInfo() {
        log.debug("==============Begin Dump Pool Info==========");
        log.debug("连接池最大连接数配置{}", pool.getMaxTotal());
        log.debug("活动连接{}", pool.getNumActive());
        log.debug("空闲连接{}", pool.getNumIdle());
        log.debug("获取前测试连接状态{}", pool.getTestOnBorrow());
        log.debug("归还前测试连接状态{}", pool.getTestOnReturn());
        log.debug("空闲时测试连接状态{}", pool.getTestWhileIdle());
        log.debug("连接获取总数统计{}", pool.getBorrowedCount());
        log.debug("连接返回总数统计{}", pool.getReturnedCount());
        log.debug("连接销毁总数统计{}", pool.getDestroyedCount());
        log.debug("JmxName={}", pool.getJmxName());
        log.debug("==============END Dump Pool ================");
    }
    /**
     * 初始化连接池配置
     * <p>说明:</p>
     * <li></li>
     * @author duanyong@jccfc.com
     * @date 2020/4/30 11:01
     * @Params poolConfig 配置
     */
    private GenericObjectPoolConfig<StorageClient1Wrapper> initPoolConfig(PoolConfig poolConfig) {
        GenericObjectPoolConfig<StorageClient1Wrapper> config = new GenericObjectPoolConfig<>();
        config.setMaxTotal(poolConfig.getMaxTotal());
        config.setMaxIdle(poolConfig.getMaxIdle());
        config.setMinIdle(poolConfig.getMinIdle());
        config.setTestOnBorrow(poolConfig.isTestOnBorrow());
        config.setMaxWaitMillis(poolConfig.getMaxWaitMillis());
        return config;
    }

    /**
     * 初始化ClientGlobal
     * @author duanyong@jccfc.com
     * @date 2020/4/30 10:47
     * @Params fastDFSConfig 配置
     * @return: void
     */
    private void initClientGlobal(FastDFSConfig fastDFSConfig) throws IOException, MyException {
        ClientGlobal.initByTrackers(fastDFSConfig.getTrackerServers());
        ClientGlobal.setG_charset(fastDFSConfig.getCharset());
        ClientGlobal.setG_secret_key(fastDFSConfig.getSecretKey());
        ClientGlobal.setG_anti_steal_token(fastDFSConfig.isAntiStealToken());
        ClientGlobal.setG_tracker_http_port(fastDFSConfig.getTrackerHttpPort());
        ClientGlobal.setG_connect_timeout(fastDFSConfig.getConnectTimeout());
        ClientGlobal.setG_network_timeout(fastDFSConfig.getNetworkTimeout());
        log.info("initClientGlobal->{}",fastDFSConfig.toString());
    }

}
